home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / GDebi / GDebi.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  24.3 KB  |  571 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import sys
  5. import os
  6. import string
  7. import warnings
  8. from warnings import warn
  9. warnings.filterwarnings('ignore', 'apt API not stable yet', FutureWarning)
  10. import apt
  11. import apt_pkg
  12. import pygtk
  13. pygtk.require('2.0')
  14. import gtk
  15. import gtk.glade as gtk
  16. import pango
  17. import gobject
  18. import vte
  19. import urllib
  20. import fcntl
  21. import posix
  22. import time
  23. import thread
  24. import re
  25. from DebPackage import DebPackage, Cache
  26. from SimpleGladeApp import SimpleGladeApp
  27. from apt.progress import InstallProgress
  28. from GDebiCommon import GDebiCommon, utf8
  29. from gettext import gettext as _
  30. GDEBI_TERMINAL_TIMEOUT = 4 * 60
  31.  
  32. class GDebi(SimpleGladeApp, GDebiCommon):
  33.     
  34.     def __init__(self, datadir, options, file = ''):
  35.         GDebiCommon.__init__(self, datadir, options, file)
  36.         localesApp = 'gdebi'
  37.         localesDir = '/usr/share/locale'
  38.         gtk.glade.bindtextdomain(localesApp, localesDir)
  39.         gtk.glade.textdomain(localesApp)
  40.         SimpleGladeApp.__init__(self, domain = 'gdebi', path = datadir + '/gdebi.glade')
  41.         icons = gtk.icon_theme_get_default()
  42.         
  43.         try:
  44.             logo = icons.load_icon('gnome-mime-application-x-deb', 48, 0)
  45.             if logo != '':
  46.                 gtk.window_set_default_icon_list(logo)
  47.         except Exception:
  48.             e = None
  49.             print 'Error loading logo'
  50.  
  51.         img = gtk.Image()
  52.         img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
  53.         self.button_install.set_image(img)
  54.         self.context = self.statusbar_main.get_context_id('context_main_window')
  55.         self.statusbar_main.push(self.context, _('Loading...'))
  56.         self.window_main.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [
  57.             ('text/uri-list', 0, 0)], gtk.gdk.ACTION_COPY)
  58.         self.window_main.set_sensitive(False)
  59.         self.notebook_details.set_sensitive(False)
  60.         self.hbox_main.set_sensitive(False)
  61.         self.window_main.show()
  62.         self.cprogress = self.CacheProgressAdapter(self.progressbar_cache)
  63.         if not self.openCache():
  64.             self.show_alert(gtk.MESSAGE_ERROR, self.error_header, self.error_body)
  65.             sys.exit(1)
  66.         
  67.         self.statusbar_main.push(self.context, '')
  68.         self.details_list = gtk.ListStore(gobject.TYPE_STRING)
  69.         column = gtk.TreeViewColumn('')
  70.         render = gtk.CellRendererText()
  71.         column.pack_start(render, True)
  72.         column.add_attribute(render, 'markup', 0)
  73.         self.treeview_details.append_column(column)
  74.         self.treeview_details.set_model(self.details_list)
  75.         if file != '' and os.path.exists(file):
  76.             self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
  77.             while gtk.events_pending():
  78.                 gtk.main_iteration()
  79.             self.open(file)
  80.             self.window_main.window.set_cursor(None)
  81.         
  82.         self.window_main.set_sensitive(True)
  83.  
  84.     
  85.     def _get_file_path_from_dnd_dropped_uri(self, uri):
  86.         ''' helper to get a useful path from a drop uri'''
  87.         path = urllib.url2pathname(uri)
  88.         path = path.strip('\r\n\x00')
  89.         if path.startswith('file:\\\\\\'):
  90.             path = path[8:]
  91.         elif path.startswith('file://'):
  92.             path = path[7:]
  93.         elif path.startswith('file:'):
  94.             path = path[5:]
  95.         
  96.         return path
  97.  
  98.     
  99.     def on_window_main_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp):
  100.         ''' call when we got a drop event '''
  101.         uri = selection.data.strip()
  102.         uri_splitted = uri.split()
  103.         for uri in uri_splitted:
  104.             path = self._get_file_path_from_dnd_dropped_uri(uri)
  105.             if path.endswith('.deb'):
  106.                 self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
  107.                 while gtk.events_pending():
  108.                     gtk.main_iteration()
  109.                 self.open(path)
  110.                 self.window_main.window.set_cursor(None)
  111.                 continue
  112.         
  113.  
  114.     
  115.     def open(self, file):
  116.         res = GDebiCommon.open(self, file)
  117.         if res == False:
  118.             self.show_alert(gtk.MESSAGE_ERROR, self.error_header, self.error_body)
  119.             return False
  120.         self.statusbar_main.push(self.context, '')
  121.         self.window_main.set_sensitive(True)
  122.         self.window_main.set_title(_('Package Installer - %s') % self._deb.pkgName)
  123.         self.label_name.set_markup(self._deb.pkgName)
  124.         self.notebook_details.set_sensitive(True)
  125.         self.hbox_main.set_sensitive(True)
  126.         buf = self.textview_description.get_buffer()
  127.         
  128.         try:
  129.             long_desc = ''
  130.             raw_desc = string.split(utf8(self._deb['Description']), '\n')
  131.             summary = raw_desc[0]
  132.             raw_desc[0] = ''
  133.             long_desc = '%s\n' % summary
  134.             for line in raw_desc:
  135.                 tmp = string.strip(line)
  136.                 if tmp == '.':
  137.                     long_desc += '\n'
  138.                     continue
  139.                 res == False
  140.                 long_desc += tmp + '\n'
  141.             
  142.             p = re.compile('^(\\s|\\t)*(\\*|0|-)', re.MULTILINE)
  143.             long_desc = p.sub('\n*', long_desc)
  144.             p = re.compile('\\n', re.MULTILINE)
  145.             long_desc = p.sub(' ', long_desc)
  146.             p = re.compile('\\s\\s+', re.MULTILINE)
  147.             long_desc = p.sub('\n', long_desc)
  148.             buf.set_text(long_desc)
  149.             tag = buf.create_tag(None, weight = pango.WEIGHT_BOLD)
  150.             iter = buf.get_iter_at_offset(0)
  151.             (start, end) = iter.forward_search('\n', gtk.TEXT_SEARCH_TEXT_ONLY, None)
  152.             buf.apply_tag(tag, iter, end)
  153.         except KeyError:
  154.             res == False
  155.             res == False
  156.             buf.set_text('No description is available')
  157.         except:
  158.             res == False
  159.  
  160.         self.label_version.set_text(self._deb['Version'])
  161.         self.label_maintainer.set_text(utf8(self._deb['Maintainer']))
  162.         self.label_priority.set_text(self._deb['Priority'])
  163.         self.label_section.set_text(utf8(self._deb['Section']))
  164.         self.label_size.set_text(self._deb['Installed-Size'] + ' KB')
  165.         buf = self.textview_filelist.get_buffer()
  166.         buf.set_text(utf8('\n'.join(self._deb.filelist)))
  167.         if not self._deb.checkDeb():
  168.             self.label_status.set_markup('<span foreground="red" weight="bold">' + _('Error: ') + self._deb._failureString + '</span>')
  169.             self.button_install.set_label(_('_Install Package'))
  170.             self.button_install.set_sensitive(False)
  171.             self.button_details.hide()
  172.             return None
  173.         self.compareDebWithCache()
  174.         self.getChanges()
  175.         if self._deb.compareToVersionInCache() == DebPackage.VERSION_SAME:
  176.             self.label_status.set_text(_('Same version is already installed'))
  177.             self.button_install.set_label(_('_Reinstall Package'))
  178.             self.button_install.grab_default()
  179.             self.button_install.set_sensitive(True)
  180.             self.button_details.hide()
  181.             return None
  182.         if len(self.install) == len(self.install):
  183.             pass
  184.         elif len(self.install) == 0:
  185.             self.button_details.hide()
  186.         else:
  187.             self.button_details.show()
  188.         self.label_status.set_markup(self.deps)
  189.         img = gtk.Image()
  190.         img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
  191.         self.button_install.set_image(img)
  192.         self.button_install.set_label(_('_Install Package'))
  193.         self.button_install.set_sensitive(True)
  194.         self.button_install.grab_default()
  195.  
  196.     
  197.     def on_button_details_clicked(self, widget):
  198.         if not self._deb:
  199.             return None
  200.         self.details_list.clear()
  201.         for rm in self.remove:
  202.             self.details_list.append([
  203.                 _('<b>To be removed: %s</b>') % rm])
  204.         
  205.         for inst in self.install:
  206.             self.details_list.append([
  207.                 _('To be installed: %s') % inst])
  208.         
  209.         self.dialog_details.set_transient_for(self.window_main)
  210.         self.dialog_details.run()
  211.         self.dialog_details.hide()
  212.  
  213.     
  214.     def on_open_activate(self, widget):
  215.         fs = gtk.FileChooserDialog(parent = self.window_main, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK), action = gtk.FILE_CHOOSER_ACTION_OPEN, title = _('Open Software Package'))
  216.         fs.set_default_response(gtk.RESPONSE_OK)
  217.         filter = gtk.FileFilter()
  218.         filter.add_pattern('*.deb')
  219.         filter.set_name(_('Software packages'))
  220.         fs.set_filter(filter)
  221.         if fs.run() == gtk.RESPONSE_OK:
  222.             self.open(fs.get_filename())
  223.         
  224.         fs.destroy()
  225.  
  226.     
  227.     def on_refresh_activate(self, widget):
  228.         self.window_main.set_sensitive(False)
  229.         self.openCache()
  230.         if self._deb:
  231.             self.open(self._deb.file)
  232.         
  233.         self.window_main.set_sensitive(True)
  234.  
  235.     
  236.     def on_about_activate(self, widget):
  237.         VERSION = VERSION
  238.         import Version
  239.         self.dialog_about.set_version(VERSION)
  240.         self.dialog_about.run()
  241.         self.dialog_about.hide()
  242.  
  243.     
  244.     def on_button_install_clicked(self, widget):
  245.         self.install_completed = False
  246.         if not self._deb:
  247.             err_header = _('File not found')
  248.             err_body = _('You tried to install a file that does not (or no longer) exist. ')
  249.             dia = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, '')
  250.             dia.set_markup('<b><big>%s</big></b>' % err_header)
  251.             dia.format_secondary_text(err_body)
  252.             dia.run()
  253.             dia.destroy()
  254.             return None
  255.         self.statusbar_main.push(self.context, _('Installing package file...'))
  256.         msg_hdr = _('You need to grant administrative rights to install software')
  257.         msg_bdy = _('\nIt is a possible security risk to install packages files manually.\nInstall software from trustworthy software distributors only.\n')
  258.         if os.getuid() != 0:
  259.             os.execl('/usr/bin/gksu', 'gksu', '--desktop', '/usr/share/applications/gdebi.desktop', '--message', '<big><b>%s</b></big>\n\n%s' % (msg_hdr, msg_bdy), '--always-ask-pass', '--', 'gdebi-gtk', '--non-interactive', self._deb.file)
  260.         
  261.         if not self.try_acquire_lock():
  262.             self.statusbar_main.push(self.context, _('Failed to install package file'))
  263.             self.show_alert(gtk.MESSAGE_ERROR, self.error_header, self.error_body)
  264.             return False
  265.         self.window_main.set_sensitive(False)
  266.         self.button_deb_install_close.set_sensitive(False)
  267.         self.dialog_deb_install.set_transient_for(self.window_main)
  268.         self.dialog_deb_install.show_all()
  269.         self.label_action.set_markup('<b><big>' + _('Installing %s') % self._deb.pkgName + '</big></b>')
  270.         dprogress = self.DpkgInstallProgress(self._deb.file, self.label_install_status, self.progressbar_install, self._term, self.expander_install)
  271.         dprogress.commit()
  272.         self.install_completed = True
  273.         self.button_deb_install_close.set_sensitive(True)
  274.         self.button_deb_install_close.grab_default()
  275.         if self.checkbutton_autoclose.get_active():
  276.             self.on_button_deb_install_close_clicked(None)
  277.         
  278.         self.label_action.set_markup('<b><big>' + _('Installation finished') + '</big></b>')
  279.         if dprogress.exitstatus == 0:
  280.             self.label_install_status.set_markup('<i>' + _("Package '%s' was installed") % os.path.basename(self._deb.file) + '</i>')
  281.         else:
  282.             self.label_install_status.set_markup('<b>' + _("Failed to install package '%s'") % os.path.basename(self._deb.file) + '</b>')
  283.             self.expander_install.set_expanded(True)
  284.         self.statusbar_main.push(self.context, _('Installation complete'))
  285.         self.openCache()
  286.         if self._cache._depcache.BrokenCount > 0:
  287.             err_header = _('Failed to completely install all dependencies')
  288.             err_body = _("To fix this run 'sudo apt-get install -f' in a terminal window.")
  289.             self.show_alert(gtk.MESSAGE_ERROR, err_header, err_body)
  290.         
  291.         self.open(self._deb.file)
  292.  
  293.     
  294.     def on_button_deb_install_close_clicked(self, widget):
  295.         self.dialog_deb_install.hide()
  296.         self.window_main.set_sensitive(True)
  297.  
  298.     
  299.     def on_checkbutton_autoclose_clicked(self, widget):
  300.         if self.install_completed:
  301.             self.on_button_deb_install_close_clicked(None)
  302.         
  303.  
  304.     
  305.     def on_window_main_delete_event(self, *args):
  306.         if self.window_main.get_property('sensitive'):
  307.             if gtk.main_level() > 0:
  308.                 gtk.main_quit()
  309.             
  310.             return False
  311.         return True
  312.  
  313.     
  314.     def create_vte(self, arg1, arg2, arg3, arg4):
  315.         self._term = vte.Terminal()
  316.         self._term.set_font_from_string('monospace 10')
  317.         return self._term
  318.  
  319.     
  320.     def show_alert(self, type, header, body = None, details = None, parent = None):
  321.         if parent is not None:
  322.             self.dialog_hig.set_transient_for(parent)
  323.         else:
  324.             self.dialog_hig.set_transient_for(self.window_main)
  325.         message = '<b><big>%s</big></b>' % header
  326.         if not body == None:
  327.             message = '%s\n\n%s' % (message, body)
  328.         
  329.         self.label_hig.set_markup(message)
  330.         if not details == None:
  331.             buffer = self.textview_hig.get_buffer()
  332.             buffer.set_text(str(details))
  333.             self.expander_hig.set_expanded(False)
  334.             self.expander_hig.show()
  335.         
  336.         if type == gtk.MESSAGE_ERROR:
  337.             self.image_hig.set_property('stock', 'gtk-dialog-error')
  338.         elif type == gtk.MESSAGE_WARNING:
  339.             self.image_hig.set_property('stock', 'gtk-dialog-warning')
  340.         elif type == gtk.MESSAGE_INFO:
  341.             self.image_hig.set_property('stock', 'gtk-dialog-info')
  342.         
  343.         res = self.dialog_hig.run()
  344.         self.dialog_hig.hide()
  345.         if res == gtk.RESPONSE_CLOSE:
  346.             return True
  347.         return False
  348.  
  349.     
  350.     class DpkgInstallProgress(object):
  351.         
  352.         def __init__(self, debfile, status, progress, term, expander):
  353.             self.debfile = debfile
  354.             self.status = status
  355.             self.progress = progress
  356.             self.term = term
  357.             self.term_expander = expander
  358.             self.time_last_update = time.time()
  359.             self.term_expander.set_expanded(False)
  360.  
  361.         
  362.         def commit(self):
  363.             
  364.             def finish_dpkg(term, pid, status, lock):
  365.                 ''' helper '''
  366.                 self.exitstatus = posix.WEXITSTATUS(status)
  367.                 lock.release()
  368.  
  369.             lock = thread.allocate_lock()
  370.             lock.acquire()
  371.             self.status.set_markup('<i>' + _("Installing '%s'...") % os.path.basename(self.debfile) + '</i>')
  372.             self.progress.pulse()
  373.             self.progress.set_text('')
  374.             (readfd, writefd) = os.pipe()
  375.             fcntl.fcntl(readfd, fcntl.F_SETFL, os.O_NONBLOCK)
  376.             cmd = '/usr/bin/dpkg'
  377.             argv = [
  378.                 cmd,
  379.                 '--status-fd',
  380.                 '%s' % writefd,
  381.                 '-i',
  382.                 self.debfile]
  383.             env = [
  384.                 'VTE_PTY_KEEP_FD=%s' % writefd,
  385.                 'DEBIAN_FRONTEND=gnome',
  386.                 'APT_LISTCHANGES_FRONTEND=gtk']
  387.             reaper = vte.reaper_get()
  388.             signal_id = reaper.connect('child-exited', finish_dpkg, lock)
  389.             pid = self.term.fork_command(command = cmd, argv = argv, envv = env)
  390.             read = ''
  391.             while lock.locked():
  392.                 while True:
  393.                     
  394.                     try:
  395.                         read += os.read(readfd, 1)
  396.                     except OSError:
  397.                         (None,)
  398.                         (errno, errstr) = (None,)
  399.                         if errno != 11:
  400.                             print errstr
  401.                         
  402.                         break
  403.                     except:
  404.                         (None,)
  405.  
  406.                     self.time_last_update = time.time()
  407.                     if read.endswith('\n'):
  408.                         statusl = string.split(read, ':')
  409.                         status = statusl[2].strip()
  410.                         if status == 'error' or status == 'conffile-prompt':
  411.                             self.term_expander.set_expanded(True)
  412.                         
  413.                         read = ''
  414.                         continue
  415.                 self.progress.pulse()
  416.                 while gtk.events_pending():
  417.                     gtk.main_iteration()
  418.                 time.sleep(0.2)
  419.                 if not self.term_expander.get_expanded() and self.time_last_update + GDEBI_TERMINAL_TIMEOUT < time.time():
  420.                     self.term_expander.set_expanded(True)
  421.                     continue
  422.             self.progress.set_fraction(1)
  423.             reaper.disconnect(signal_id)
  424.  
  425.  
  426.     
  427.     class InstallProgressAdapter(InstallProgress):
  428.         
  429.         def __init__(self, progress, term, label, term_expander):
  430.             InstallProgress.__init__(self)
  431.             self.progress = progress
  432.             self.term = term
  433.             self.term_expander = term_expander
  434.             self.finished = False
  435.             self.action = label
  436.             self.time_last_update = time.time()
  437.             reaper = vte.reaper_get()
  438.             reaper.connect('child-exited', self.child_exited)
  439.             self.env = [
  440.                 'VTE_PTY_KEEP_FD=%s' % self.writefd,
  441.                 'DEBIAN_FRONTEND=gnome',
  442.                 'APT_LISTCHANGES_FRONTEND=gtk']
  443.  
  444.         
  445.         def child_exited(self, term, pid, status):
  446.             self.apt_status = posix.WEXITSTATUS(status)
  447.             self.finished = True
  448.  
  449.         
  450.         def error(self, pkg, errormsg):
  451.             self.term_expander.set_expanded(True)
  452.  
  453.         
  454.         def conffile(self, current, new):
  455.             self.term_expander.set_expanded(True)
  456.  
  457.         
  458.         def startUpdate(self):
  459.             apt_pkg.PkgSystemUnLock()
  460.             self.action.set_markup('<i>' + _('Installing dependencies...') + '</i>')
  461.             self.progress.set_fraction(0)
  462.             self.progress.set_text('')
  463.  
  464.         
  465.         def statusChange(self, pkg, percent, status):
  466.             self.progress.set_fraction(percent / 100)
  467.             self.progress.set_text(status)
  468.             self.time_last_update = time.time()
  469.  
  470.         
  471.         def updateInterface(self):
  472.             InstallProgress.updateInterface(self)
  473.             while gtk.events_pending():
  474.                 gtk.main_iteration()
  475.             if not self.term_expander.get_expanded() and self.time_last_update + GDEBI_TERMINAL_TIMEOUT < time.time():
  476.                 self.term_expander.set_expanded(True)
  477.             
  478.  
  479.         
  480.         def fork(self):
  481.             return self.term.forkpty(envv = self.env)
  482.  
  483.         
  484.         def waitChild(self):
  485.             while not self.finished:
  486.                 self.updateInterface()
  487.             return self.apt_status
  488.  
  489.  
  490.     
  491.     class FetchProgressAdapter(apt.progress.FetchProgress):
  492.         
  493.         def __init__(self, progress, action, main):
  494.             self.progress = progress
  495.             self.action = action
  496.             self.main = main
  497.  
  498.         
  499.         def start(self):
  500.             self.action.set_markup('<i>' + _('Downloading additional package files...') + '</i>')
  501.             self.progress.set_fraction(0)
  502.  
  503.         
  504.         def stop(self):
  505.             pass
  506.  
  507.         
  508.         def pulse(self):
  509.             at_item = min(self.currentItems + 1, self.totalItems)
  510.             if self.currentCPS > 0:
  511.                 self.progress.set_text(_('File %s of %s at %sB/s') % (at_item, self.totalItems, apt_pkg.SizeToStr(self.currentCPS)))
  512.             else:
  513.                 self.progress.set_text(_('File %s of %s') % (at_item, self.totalItems))
  514.             self.progress.set_fraction(self.currentBytes / self.totalBytes)
  515.             while gtk.events_pending():
  516.                 gtk.main_iteration()
  517.             return True
  518.  
  519.         
  520.         def mediaChange(self, medium, drive):
  521.             msg = _("Please insert '%s' into the drive '%s'" % (medium, drive))
  522.             dialog = gtk.MessageDialog(parent = self.main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_QUESTION, buttons = gtk.BUTTONS_OK_CANCEL)
  523.             dialog.set_markup(msg)
  524.             res = dialog.run()
  525.             dialog.destroy()
  526.             if res == gtk.RESPONSE_OK:
  527.                 return True
  528.             return False
  529.  
  530.  
  531.     
  532.     class CacheProgressAdapter(apt.progress.FetchProgress):
  533.         
  534.         def __init__(self, progressbar):
  535.             self.progressbar = progressbar
  536.  
  537.         
  538.         def update(self, percent):
  539.             self.progressbar.show()
  540.             self.progressbar.set_fraction(percent / 100)
  541.             while gtk.events_pending():
  542.                 gtk.main_iteration()
  543.  
  544.         
  545.         def done(self):
  546.             self.progressbar.hide()
  547.  
  548.  
  549.  
  550. if __name__ == '__main__':
  551.     app = GDebi('data/', None)
  552.     pkgs = [
  553.         '3ddesktop']
  554.     for pkg in pkgs:
  555.         print 'installing %s' % pkg
  556.         app._cache[pkg].markInstall()
  557.     
  558.     for pkg in app._cache:
  559.         if pkg.markedInstall or pkg.markedUpgrade:
  560.             print pkg.name
  561.         
  562.     
  563.     apt_pkg.PkgSystemLock()
  564.     app.dialog_deb_install.set_transient_for(app.window_main)
  565.     app.dialog_deb_install.show_all()
  566.     fprogress = app.FetchProgressAdapter(app.progressbar_install)
  567.     iprogress = app.InstallProgressAdapter(app.progressbar_install, app._term)
  568.     res = app._cache.commit(fprogress, iprogress)
  569.     print 'commit retured: %s' % res
  570.  
  571.